
package com.pubinfo.passbook.common.config;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ClassUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.util.CollectionUtils;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Configuration
@EnableSwagger2WebMvc
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfiguration {
  @Value("${knife4j.enable}")
  Boolean isEnable;
  //
  //private final TypeResolver typeResolver;
  //private final OpenApiExtensionResolver openApiExtensionResolver;
  private String env;
  
  //@Autowired
  //public SwaggerConfiguration(TypeResolver typeResolver, OpenApiExtensionResolver openApiExtensionResolver, ApplicationContext context) {
  //  this.typeResolver = typeResolver;
  //  this.openApiExtensionResolver = openApiExtensionResolver;
  //  env = context.getEnvironment().getActiveProfiles()[0];
  //}
  //
  @Autowired
  public SwaggerConfiguration(ApplicationContext context) {
    env = context.getEnvironment().getActiveProfiles()[0];
  }
  
  private ApiKey apiKey() {
    return new ApiKey("BearerToken", "Authorization", "header");
  }
  
  private List<ApiKey> securitySchemes() {
    return CollectionUtil.newArrayList(new ApiKey("BearerToken", "Authorization", "header"));
  }
  
  @Bean(value = "defaultApi")
  public Docket defaultApi() {
    String packageStr = "com.pubinfo.passbook.api.controller.bill";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("1.电子票据报账接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    
    return docket;
  }
  
  @Bean(value = "engineApi")
  public Docket engineApi() {
    String packageStr = "com.pubinfo.passbook.api.controller.engine";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("4.电子票据报账-计算引擎相关接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "ruleApi")
  public Docket ruleApi() {
    String packageStr = "com.pubinfo.passbook.api.controller.rule";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("3.电子票据报账-审核规则相关接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "esbApi")
  public Docket esbApi() {
    String packageStr = "com.pubinfo.passbook.esb.controller";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("7.电子票据报账-esb相关接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "systemApi")
  public Docket systemApi() {
    String packageStr = "com.pubinfo.passbook.api.controller.system";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("2.电子票据报账-系统管理相关接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "contractApi")
  public Docket contractApi() {
    String packageStr = "com.pubinfo.passbook.api.controller.contract";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("6.迁改赔补系统接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "otherApi")
  public Docket otherApi() {
    String packageStr = "com.pubinfo.passbook.api.controller.other";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("5.电子票据报账-其他")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  private SecurityContext securityContext() {
    return SecurityContext.builder()
        .securityReferences(defaultAuth())
        .build();
  }
  
  List<SecurityReference> defaultAuth() {
    AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
    AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
    authorizationScopes[0] = authorizationScope;
    return CollectionUtil.newArrayList(new SecurityReference("BearerToken", authorizationScopes));
  }
  
  @Bean(value = "dataBillApi")
  public Docket dataBillApi() {
    String packageStr = "com.pubinfo.passbook.data.controller.bill";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("1.电子票据报账数据-报账相关接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "forwardApi")
  public Docket forwardApi() {
    String packageStr = "com.pubinfo.passbook.data.controller.forward";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("1.电子票据报账数据-转发相关接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "openApi")
  public Docket openApi() {
    String packageStr = "com.pubinfo.passbook.data.controller.open";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("1.电子票据报账数据-对外开放接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "dataOtherApi")
  public Docket dataOtherApi() {
    String packageStr = "com.pubinfo.passbook.data.controller.other";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("1.电子票据报账数据-其他接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "syncApi")
  public Docket syncApi() {
    String packageStr = "com.pubinfo.passbook.data.controller.sync";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("1.电子票据报账数据-同步相关接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  @Bean(value = "dataSystemApi")
  public Docket dataSystemApi() {
  
    String packageStr = "com.pubinfo.passbook.data.controller.system";
    Set<Class<?>> classSet = ClassUtil.scanPackage(packageStr);
    Docket docket = new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).enable(isEnable && !CollectionUtils.isEmpty(classSet))
        .groupName("1.电子票据报账数据-系统相关接口")
        .select()
        .apis(RequestHandlerSelectors.basePackage(packageStr))
        .paths(PathSelectors.any())
        .build()
        .securityContexts(CollectionUtil.newArrayList(securityContext()));
    // .securitySchemes(securitySchemes());
    return docket;
  }
  
  private ApiInfo apiInfo() {
    List<VendorExtension> extensions = new ArrayList<>();
    StringVendorExtension vendorExtension = new StringVendorExtension("环境", env);
    extensions.add(vendorExtension);
    return new ApiInfoBuilder()
        .description("# swagger-bootstrapRESTful APIs")
        .termsOfServiceUrl("http://www.xx.com/")
        .contact("2465915902@qq.com").extensions(extensions)
        .version("1.0")
        .build();
  }
}
